package com.example.my_self_view.practice2

import android.content.Context
import android.graphics.*
import android.os.Handler
import android.os.Looper
import android.util.AttributeSet
import android.util.TypedValue
import android.view.View
import com.example.my_self_view.R
import com.example.my_self_view.practice2.bean.Circle
import com.example.my_self_view.practice2.bean.Rectangle
import com.example.my_self_view.practice2.bean.Triangle
import kotlin.math.sqrt

/**
 * @dsc     简介
 * @Author  LiWeiZhong
 * @Date    2025/1/15 9:17
 * @Version 1.0
 */
class TransferView: View {

    private val rectanglePaint by lazy { Paint() }
    private val circlePaint by lazy { Paint() }
    private val trianglePaint by lazy { Paint() }

    private val rect by lazy { Rect() }
    private val rectF by lazy { RectF() }
    private val triangle by lazy { Triangle() }
    private val circle by lazy { Circle() }
    private val rectangle by lazy { Rectangle() }

    private var shapeSwitcher: Runnable? = null
    private val shapeList = arrayListOf("triangle", "circle", "rectangle")
    private var currentShapeIndex = 0
    private var currentShape = shapeList[currentShapeIndex]

    private val mHandler by lazy { Handler(Looper.getMainLooper()) }
    private var boundingSquareWidth: Int = 100
    private var transferInterval: Int = 1
    private var triangleColor: Int = Color.parseColor("#00BF7E")
    private var circleColor: Int = Color.parseColor("#FF4081")
    private var rectangleColor: Int = Color.parseColor("#3F51B5")

    // 开始切换图形
    fun startSwitchingShapes() {
        if (shapeSwitcher != null) {
            mHandler.postDelayed(shapeSwitcher!!, transferInterval * 1000L)
        }
    }

    // 停止切换图形
    fun stopSwitchingShapes() {
        if (shapeSwitcher != null) {
            mHandler.removeCallbacks(shapeSwitcher!!)
        }
    }

    constructor(context: Context): this(context, null){}

    constructor(context: Context, attrs: AttributeSet?): this(context, attrs, 0) {}

    constructor(context: Context, attrs: AttributeSet?, defStyleAttrs: Int): this(context, attrs, defStyleAttrs, 0) {}

    constructor(context: Context, attrs: AttributeSet?, defStyleAttrs: Int, defStyleRes: Int): super(context, attrs, defStyleAttrs, defStyleRes) {
        initData(context, attrs)
    }

    private fun initData(context: Context, attrs: AttributeSet?) {
        val attributes = context.obtainStyledAttributes(attrs, R.styleable.TransferView)
        attributes.apply {
            try {
                boundingSquareWidth = attributes.getDimensionPixelSize(R.styleable.TransferView_boundingSquareWidth, boundingSquareWidth)
                transferInterval = attributes.getInteger(R.styleable.TransferView_transferInterval, transferInterval)
                triangleColor = attributes.getColor(R.styleable.TransferView_triangleColor, triangleColor)
                circleColor = attributes.getColor(R.styleable.TransferView_circleColor, circleColor)
                rectangleColor = attributes.getColor(R.styleable.TransferView_rectangleColor, rectangleColor)

                // triangle
                initPaint(trianglePaint, triangleColor)
                // circle
                initPaint(circlePaint, circleColor)
                // rectangle
                initPaint(rectanglePaint, rectangleColor)
                // runnable
                initRunnable()
            } finally {
                recycle()
            }
        }
    }

    private fun initRunnable() {
        if (shapeSwitcher == null) {
            shapeSwitcher = object : Runnable{
                override fun run() {
                    // 切换图形
                    currentShapeIndex = (currentShapeIndex + 1) % shapeList.size
                    currentShape = shapeList[currentShapeIndex]
                    invalidate()
                    mHandler.postDelayed(this, transferInterval * 1000L)
                }
            }
        }
    }

    private fun initPaint(paint: Paint, color: Int) {
        paint.apply {
            isAntiAlias = true
            isDither = true
            this.color = color
            style = Paint.Style.FILL
        }
    }

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec)

        val widthMode = MeasureSpec.getMode(widthMeasureSpec)
        val heightMode = MeasureSpec.getMode(heightMeasureSpec)

        var width = MeasureSpec.getSize(widthMeasureSpec)
        var height = MeasureSpec.getSize(heightMeasureSpec)

        if (widthMode == MeasureSpec.AT_MOST) {
            width = boundingSquareWidth + paddingStart + paddingEnd
        }
        if (heightMode == MeasureSpec.AT_MOST) {
            height = boundingSquareWidth + paddingTop + paddingBottom
        }

        setMeasuredDimension(width, height)
    }

    private fun valueToPx(value: Float, type: Int): Float {
        return TypedValue.applyDimension(type, value, resources.displayMetrics)
    }

    override fun onDraw(canvas: Canvas) {
        when (currentShape) {
            "triangle" -> {
                // 画三角形 h = (g3 / 2) * a   a = h / (g3 / 2)   a = h * 2 / g3
                // 这是高为 100dp
//                val h = valueToPx(100f, TypedValue.COMPLEX_UNIT_DIP)
//                val triangleLen = h * 2f / sqrt(3f)
                // 这是边为 100dp
                val triangleLen = valueToPx(100f, TypedValue.COMPLEX_UNIT_DIP)
                val h = triangleLen * sqrt(3f) / 2f
                triangle.apply {
                    startPoint.apply {
                        x = width / 2f
                        y = height / 2f - h / 2f
                    }
                    secondPoint.apply {
                        x = startPoint.x + triangleLen / 2f
                        y = startPoint.y + h
                    }
                    lastPoint.apply {
                        x = startPoint.x - triangleLen / 2f
                        y = startPoint.y + h
                    }
                }
                drawTriangle(canvas, triangle)
            }
            "circle" -> {
                // 画圆形
                val circleRadius = valueToPx(50f, TypedValue.COMPLEX_UNIT_DIP)
                circle.apply {
                    centerXY.apply {
                        x = width / 2f
                        y = height / 2f
                    }
                    radius = circleRadius
                }
                drawCircle(canvas, circle)
            }
            "rectangle" -> {
                // 画矩形
                val rectangleWidth = valueToPx(100f, TypedValue.COMPLEX_UNIT_DIP)
                val rectangleHeight = valueToPx(100f, TypedValue.COMPLEX_UNIT_DIP)
                rectangle.apply {
                    width = rectangleWidth
                    height = rectangleHeight
                    startPoint.apply {
                        x = this@TransferView.width / 2f - width / 2f
                        y = this@TransferView.height / 2f - height / 2f
                    }
                }
                drawRectangle(canvas, rectangle)
            }
        }
    }

    private fun drawTriangle(canvas: Canvas?, triangle: Triangle) {
        canvas?.save()

        // 创建Path对象
        val path = Path()

        // 移动到起点
        path.moveTo(triangle.startPoint.x, triangle.startPoint.y)

        // 连接点2
        path.lineTo(triangle.secondPoint.x, triangle.secondPoint.y)

        // 连接点3
        path.lineTo(triangle.lastPoint.x, triangle.lastPoint.y)

        // 闭合路径
        path.close()

        // 绘制路径
        canvas?.drawPath(path, trianglePaint)

        canvas?.restore()
    }

    private fun drawCircle(canvas: Canvas?, circle: Circle) {
        canvas?.save()

        canvas?.drawCircle(circle.centerXY.x, circle.centerXY.y, circle.radius, circlePaint)

        canvas?.restore()
    }

    private fun drawRectangle(canvas: Canvas?, rectangle: Rectangle) {
        canvas?.save()

        val left = rectangle.startPoint.x
        val right = left + rectangle.width
        val top = rectangle.startPoint.y
        val bottom = top + rectangle.height

        canvas?.drawRect(left, top, right, bottom, rectanglePaint)

        canvas?.restore()
    }
}